package com.example.camerademoexcercies1;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.SurfaceTexture;
import android.hardware.Camera;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraManager;
import android.hardware.camera2.params.StreamConfigurationMap;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.util.Size;
import android.util.SparseIntArray;
import android.view.KeyEvent;
import android.view.Surface;
import android.view.TextureView;
import android.view.View;
import android.widget.ImageButton;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.constraintlayout.widget.ConstraintLayout;

import com.example.camerademoexcercies1.tool.LogTool;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class SimplifyRecorder extends AppCompatActivity implements View.OnClickListener {

    /**
     * 存在的问题：
     * 1.视频分辨率
     * 2.应该用camera2来重写
     * 3.把预览功能提取出来
     * 4.田横
     */

    //记录用户首次点击返回键的时间
    private long firstTime = 0;
    private TextureView textureView;
    private Surface previewSurface;
    private ImageButton btn_recorder;
    private boolean isRecording;
    private String cameraId;
    private ConstraintLayout bottom_linearLayout;
    private CameraManager cameraManager;
    private CameraCharacteristics cameraCharacteristics;
    private MediaRecorder recorder;
    private File videoFile;
    private Camera camera;
    Camera.Parameters parameters;
    private int optimalSizeWidth;
    private int optimalSizeHeight;
    private static final SparseIntArray ORIENTATIONS = new SparseIntArray();
    private Handler mHandler;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_simplify_recorder);
        initEvent();
        initTexture();
    }

    //    初始化Surface和预览尺寸
    private void initTexture() {
        textureView.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() {
            @Override
            public void onSurfaceTextureAvailable(@NonNull SurfaceTexture surface, int width, int height) {
                final Size optimalSize = getOptimalSize(width, height);
                optimalSizeWidth = optimalSize.getWidth();
                optimalSizeHeight = optimalSize.getHeight();
//                optimalSizeWidth = 1920;
//                optimalSizeHeight = 1080;
                say("计算的到Text的最佳尺寸:\t" + optimalSizeWidth + "*" + optimalSizeHeight);
                surface.setDefaultBufferSize(optimalSizeWidth, optimalSizeHeight);
                previewSurface = new Surface(surface);
                initCamera();
                try {
                    camera.setPreviewTexture(surface);
                    camera.startPreview();
                    mHandler.sendEmptyMessage(0x01);//启动对焦
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void onSurfaceTextureSizeChanged(@NonNull SurfaceTexture surface, int width, int height) {

            }

            @Override
            public boolean onSurfaceTextureDestroyed(@NonNull SurfaceTexture surface) {
                return false;
            }

            @Override
            public void onSurfaceTextureUpdated(@NonNull SurfaceTexture surface) {

            }
        });
    }

    //    初始化Camera
    private void initCamera() {
        //  视频为什么有时候是旋转的
        camera = Camera.open(Camera.CameraInfo.CAMERA_FACING_BACK);
        if (camera != null) {
            parameters = camera.getParameters();
            parameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);//关闭闪光灯
            parameters.setFocusMode(Camera.Parameters.FLASH_MODE_AUTO); //对焦设置为自动
            parameters.setPreviewSize(optimalSizeWidth, optimalSizeHeight);//设置预览尺寸
            parameters.setPictureSize(optimalSizeWidth, optimalSizeHeight);//设置图片尺寸  就拿预览尺寸作为图片尺寸,其实他们基本上是一样的
            parameters.set("orientation", "portrait");//相片方向
            parameters.set("rotation", 90); //相片镜头角度转90度（默认摄像头是横拍）
            camera.setParameters(parameters);//添加参数
            camera.setDisplayOrientation(90);//设置显示方向
            /*List<String> supportedFocusModes = parameters.getSupportedFocusModes();

            for (String mode : supportedFocusModes) {
                if (mode.equals(Camera.Parameters.FOCUS_MODE_AUTO)) {
                    say("get mode : "+mode);
                    parameters.setFocusMode(mode);
                    break;
                }
            }*/
            camera.setParameters(parameters);
        }

    }

    //    初始化mediaRecorder
    private void initMediaRecorder() {
        File videoRootPath = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM),
                "MediaRecorderStorage");
        if (!videoRootPath.exists() && videoRootPath.mkdir()) {
            say("根目录:videoRootPath(" + videoRootPath.toString() + ")创建失败");
        } else {
            videoFile = new File(videoRootPath, "video" + System.currentTimeMillis() + ".mp4");
            say("输出文件(" + videoFile);
        }

        //    创建mediaPlayer对象
        recorder = new MediaRecorder();
        camera.unlock();
        recorder.setCamera(camera);
        //    这两项需要放在setOutputFormat之前
        recorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
        recorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);

        recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);

        recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
        recorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);
        recorder.setVideoSize(optimalSizeWidth, optimalSizeHeight);
        recorder.setVideoFrameRate(20);
        recorder.setVideoEncodingBitRate(3 * optimalSizeWidth * optimalSizeHeight);
        recorder.setOrientationHint(90);
        //        指定surface
        recorder.setPreviewDisplay(previewSurface);
        //        设置记录会话的最大持续时间（毫秒）
        recorder.setMaxDuration(30 * 1000);
        recorder.setOutputFile(videoFile.getAbsolutePath());
        say("mediaRecorder 初始化完成");
    }

    //    点击事件
    @Override
    public void onClick(View v) {
        if (v.getId() == R.id.btn_simple_record) {
//            开始录制转停止录制
            if (isRecording) {
                recorder.stop();
                recorder.release();
                recorder = null;
                say("————1111111111111111stop recording————");
                isRecording = false;
                btn_recorder.setImageResource(R.drawable.icon_recorder_white);
                bottom_linearLayout.setAlpha(1);
                camera.startPreview();
            } else {
                try {
                    if (recorder == null) {
                        initMediaRecorder();
                    }
                    recorder.prepare();
                    recorder.start();
                    say("————start recording————");
                    isRecording = true;
                    btn_recorder.setImageResource(R.drawable.icon_recorder_red);
                    bottom_linearLayout.setAlpha(0.1F);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    //    绑定组件、事件
    private void initEvent() {
        isRecording = false;
        cameraId = "0";
        btn_recorder = findViewById(R.id.btn_simple_record);
        textureView = findViewById(R.id.texture_recorder_view);
        cameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
        bottom_linearLayout = (ConstraintLayout) findViewById(R.id.bottom_linearLayout);
        btn_recorder.setOnClickListener(this);
        mHandler = new Handler() {
            @SuppressLint("HandlerLeak")
            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
                switch (msg.what) {
                    case 0x01:
                        camera.autoFocus(new Camera.AutoFocusCallback() { //自动对焦
                            @Override
                            public void onAutoFocus(boolean success, Camera camera) {
                                say("success : " + success);
                            }
                        });
                        mHandler.sendEmptyMessageDelayed(0x01, 2 * 1000);//2秒之后在对焦一次,一直重复自动对焦
                        break;
                    default:
                        break;
                }
            }
        };

    }

    //    获取当前Characteristic分辨率最高的Size
    public Size getOptimalSize(int textureWidth, int textureHeight) {
        try {
            cameraCharacteristics = cameraManager.getCameraCharacteristics(cameraId);
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
        StreamConfigurationMap configurationMap = //一份详细的配置表
                cameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
        Size[] sizeList = configurationMap.getOutputSizes(SurfaceTexture.class); //提供一个可输出Size的类
        List<Size> readyList = new ArrayList<>();
//            先找尺寸接近的，再找其中分辨率最高的
        float bestRatio = (float) textureHeight / textureWidth;
        int maxSize = 0;
        for (Size size : sizeList) {
            if (Math.abs(((float) size.getWidth() / size.getHeight() - bestRatio)) < 0.1) {
                readyList.add(size);
            }
        }
        say("第一轮筛选的size有：" + readyList.toString());
        for (Size size : readyList) {
            if (size.getWidth() > maxSize) {
                maxSize = size.getWidth();
                sizeList[0] = size;
            }
        }
        return sizeList[0];
    }

    //    返回退出功能
    @Override
    public boolean onKeyUp(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_UP) {
            long secondTime = System.currentTimeMillis();
            if (secondTime - firstTime > 2000) {
                Toast.makeText(SimplifyRecorder.this, "再按一次退出程序", (int) 2000).show();
                firstTime = secondTime;
                return true;
            } else {
                finish();
                System.exit(0);
            }
        }
        return super.onKeyUp(keyCode, event);
    }

    //    打印
    public void say(String word) {
        LogTool.log(word);
    }
}